ARMGNU ?= aarch64-linux-gnu

board ?= rpi4

ifeq ($(board), rpi3)
COPS += -DCONFIG_BOARD_PI3B
QEMU_FLAGS  += -machine raspi3
else ifeq ($(board), rpi4)
COPS += -DCONFIG_BOARD_PI4B
QEMU_FLAGS  += -machine raspi4
endif

#if need hypervisor
#COPS += -DCONFIG_VIRT
#ASMOPS += -DCONFIG_VIRT

COPS += -g -Wall -nostdlib \
        -Iinclude -Iinclude/kernel -Iinclude/uapi \
        -Iarch/arm64/include \
		-Idrivers/base \
		-Iinclude/hypervisor \
        -mgeneral-regs-only

ASMOPS = -g \
         -Iinclude -Iinclude/kernel -Iinclude/uapi \
         -Iarch/arm64/include \
		 -Idrivers/base \
		 -Iinclude/hypervisor

BUILD_DIR = build
SRC_DIRS = arch/arm64/boot arch/arm64/kernel arch/arm64/mm arch/arm64/drivers \
           kernel/sched kernel/mm kernel/irq kernel/printk kernel/kernel_main \
           drivers/serial \
           lib lib/string lib/asm lib/test \
           init \
		   hypervisor

# 查找所有源文件
C_FILES = $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c))
ASM_FILES = $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.S))

# 生成目标文件路径
OBJ_FILES = $(C_FILES:%.c=$(BUILD_DIR)/%_c.o)
OBJ_FILES += $(ASM_FILES:%.S=$(BUILD_DIR)/%_s.o)

all : hbos.bin

clean :
	rm -rf $(BUILD_DIR) *.bin *.elf *.map 


# C 文件编译规则
$(BUILD_DIR)/%_c.o: %.c
	@mkdir -p $(@D)
	$(ARMGNU)-gcc $(COPS) -MMD -c $< -o $@

# 汇编文件编译规则  
# 汇编文件编译规则 - 修改这里！
$(BUILD_DIR)/%_s.o: %.S
	@mkdir -p $(@D)
	$(ARMGNU)-gcc $(ASMOPS) -MMD -c -D__ASSEMBLY__ $< -o $@

DEP_FILES = $(OBJ_FILES:%.o=%.d)
-include $(DEP_FILES)

hbos.bin: arch/arm64/boot/linker.ld $(OBJ_FILES)
	$(ARMGNU)-ld -T arch/arm64/boot/linker.ld -Map hbos.map -o $(BUILD_DIR)/hbos.elf $(OBJ_FILES)
	$(ARMGNU)-objcopy $(BUILD_DIR)/hbos.elf -O binary hbos.bin
	cp $(BUILD_DIR)/hbos.elf hbos.elf

QEMU_FLAGS += -nographic

# 带虚拟化的编译
# 带虚拟化的编译
virt:
	@echo "Building with virtualization support"
	$(MAKE) COPS="-DCONFIG_VIRT $(COPS)" ASMOPS="-DCONFIG_VIRT $(ASMOPS)" hbos.bin

run:
	qemu-system-aarch64 $(QEMU_FLAGS) -kernel hbos.bin

debug:
	qemu-system-aarch64 $(QEMU_FLAGS) -kernel hbos.bin -S -s

debug-src:
	@echo "C_FILES: $(C_FILES)"
	@echo "ASM_FILES: $(ASM_FILES)"
	@echo "OBJ_FILES: $(OBJ_FILES)"
